package com.school.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.school.entity.*;
import com.school.repository.RealisticRecordRepository;
import com.school.service.RealisticRecordService;
import com.school.untils.AuthMDA;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;
import java.io.IOException;
import java.util.*;

@Service
@Transactional
public class RealisticRecordServiceImp implements RealisticRecordService {
    @Autowired
    RealisticRecordRepository realisticRecordRepository;
    @Value("${web.upload.path}")
    String basePath;

    /**
     * 增加
     * @param fileList,realisticRecord
     * @return
     */
    @Override
    public RealisticRecord addRealisticRecord(List<MultipartFile> fileList, RealisticRecord realisticRecord) throws IOException {
        realisticRecord.setFiles(AuthMDA.removeBrackets(AuthMDA.setFiles(fileList,basePath).toString()));
        realisticRecord.setCreateDate(new Date());
        realisticRecord.setUpdateDate(new Date());
        return realisticRecordRepository.save(realisticRecord);
    }

    /**
     * 查询所有
     * @param realisticRecord
     */
    @Override
    public List<RealisticRecord> findAll(RealisticRecord realisticRecord) {
        Specification querySpecification = new Specification() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if(realisticRecord != null)
                {
                    String areaCode = realisticRecord.getAreaCode();
                    String schoolId = realisticRecord.getSchoolId();
                    String grade = realisticRecord.getGrade();
                    String classId = realisticRecord.getClassId();
                    String studentId = realisticRecord.getStudentId();
                    if (!StringUtils.isEmpty(areaCode))
                    {
                        predicates.add(criteriaBuilder.equal(root.get("areaCode").as(String.class),areaCode));
                    }
                    if (!StringUtils.isEmpty(schoolId))
                    {
                        predicates.add(criteriaBuilder.equal(root.get("schoolId").as(String.class),schoolId));
                    }
                    if (!StringUtils.isEmpty(grade))
                    {
                        predicates.add(criteriaBuilder.equal(root.get("grade").as(String.class),grade));
                    }
                    if (!StringUtils.isEmpty(classId))
                    {
                        predicates.add(criteriaBuilder.equal(root.get("classId").as(String.class),classId));
                    }
                    if (!StringUtils.isEmpty(studentId))
                    {
                        predicates.add(criteriaBuilder.equal(root.get("studentId").as(String.class),studentId));
                    }
                }
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
        return realisticRecordRepository.findAll(querySpecification);
    }

    /**
     * 修改
     * @param realisticRecord
     * @return
     */
    @Override
    public RealisticRecord updateRealisticRecord(RealisticRecord realisticRecord) {
        realisticRecord.setUpdateDate(new Date());
        return realisticRecordRepository.saveAndFlush(realisticRecord);
    }

    /**
     * 查看详情
     * @param id
     */
    @Override
    public RealisticRecord getDetailsById(String id) {
        return realisticRecordRepository.findById(Integer.valueOf(id)).get();
    }

    /**
     * 删除
     * @param id
     */
    @Override
    public void deleteRealisticRecord(String id) {
        RealisticRecord realisticRecord = null;
        try {
            realisticRecord = realisticRecordRepository.findById(Integer.valueOf(id)).get();
            realisticRecordRepository.delete(realisticRecord);
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
    }

    /**
     * 批量删除
     * @param idList
     */
    @Override
    public void deleteRealisticRecordList(String idList) {
        String[] split = idList.split(",");
        List<Integer> list = new ArrayList<>();
        for (String s : split) {
            list.add(Integer.parseInt(s));
        }
        realisticRecordRepository.deleteRealisticRecordsByIdIn(list);
    }

    /**
     * 根据条件分页查询
     * @param realisticRecord,page,size
     */
    @Override
    public Page<RealisticRecord> specificPageQueryRealisticRecordList(RealisticRecord realisticRecord,int page, int size) {
        Specification querySpecification = new Specification() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if(realisticRecord != null)
                {
                    String areaCode = realisticRecord.getAreaCode();
                    String schoolId = realisticRecord.getSchoolId();
                    String grade = realisticRecord.getGrade();
                    String classId = realisticRecord.getClassId();
                    String studentId = realisticRecord.getStudentId();
                    Integer dimension = realisticRecord.getDimension();
                    String classify = realisticRecord.getClassify();
                    String activityName = realisticRecord.getActivityName();
                    Integer auditStatus = realisticRecord.getAuditStatus();
                    String scholastic = realisticRecord.getScholastic();
                    String semester = realisticRecord.getSemester();
                    if (!StringUtils.isEmpty(areaCode))
                    {
                        predicates.add(criteriaBuilder.equal(root.get("areaCode").as(String.class),areaCode));
                    }
                    if (!StringUtils.isEmpty(schoolId))
                    {
                        predicates.add(criteriaBuilder.equal(root.get("schoolId").as(String.class),schoolId));
                    }
                    if (!StringUtils.isEmpty(grade))
                    {
                        predicates.add(criteriaBuilder.equal(root.get("grade").as(String.class),grade));
                    }
                    if (!StringUtils.isEmpty(classId))
                    {
                        predicates.add(criteriaBuilder.equal(root.get("classId").as(String.class),classId));
                    }
                    if (!StringUtils.isEmpty(studentId))
                    {
                        predicates.add(criteriaBuilder.equal(root.get("studentId").as(String.class),studentId));
                    }
                    if (dimension != null) {
                        predicates.add(criteriaBuilder.equal(root.get("dimension").as(Integer.class), dimension));
                    }
                    if (!StringUtils.isEmpty(classify))
                    {
                        predicates.add(criteriaBuilder.equal(root.get("classify").as(String.class),classify));
                    }
                    if (!StringUtils.isEmpty(activityName))
                    {
                        predicates.add(criteriaBuilder.like(root.get("activityName").as(String.class),"%" + activityName + "%"));
                    }
                    if (!StringUtils.isEmpty(scholastic))
                    {
                        predicates.add(criteriaBuilder.equal(root.get("scholastic").as(String.class),scholastic));
                    }
                    if (!StringUtils.isEmpty(semester))
                    {
                        predicates.add(criteriaBuilder.equal(root.get("semester").as(String.class),semester));
                    }
                    if (auditStatus != null) {
                        predicates.add(criteriaBuilder.equal(root.get("auditStatus").as(Integer.class), auditStatus));
                    }
                }
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
        PageRequest pageRequest = PageRequest.of(page-1, size, Sort.by(Sort.Direction.DESC,"updateDate"));
        return realisticRecordRepository.findAll(querySpecification,pageRequest);
    }


    /**
     * 审核状态变更
     * @param id,audit
     */
    @Override
    public void updateAudit(String id,int audit) {
        RealisticRecord realisticRecord;
        try {
            realisticRecord = realisticRecordRepository.findById(Integer.valueOf(id)).get();
            realisticRecord.setAuditStatus(audit);
            realisticRecord.setUpdateDate(new Date());
            realisticRecord.setUpdateBy(realisticRecord.getUpdateBy());
            realisticRecord.setRejectionReason("");
            realisticRecordRepository.saveAndFlush(realisticRecord);
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
    }

    /**
     * 查询不同状态的所有
     * @return
     */
    @Override
    public List<RealisticRecord> findListByAuditStatus(int auditStatus) {
        return realisticRecordRepository.findRealisticRecordsByAuditStatus(auditStatus);
    }

    /**
     * 事实材料添加
     * @param fileList,id,path
     * @return
     */
    @Override
    public JSONObject updateFile(List<MultipartFile> fileList,String path) throws IOException {
        JSONObject resPath = new JSONObject();
        List<String> filesList = new ArrayList<>();
        filesList.add(path);
        for(int i = 0; i < fileList.size(); i ++){
            String fileName = AuthMDA.createFileName(i,fileList.get(i));
            String filePath = basePath + fileName;
            boolean upload = AuthMDA.upload(filePath, fileList.get(i));
            if (upload) {
                String files = AuthMDA.UPLOAD_PATH + fileName;
                filesList.add(files);
            } else{
                filesList.add("");
            }
        }
        resPath.put("picPath", filesList.toArray());
        return resPath;
    }

    /**
     * 审核状态批量变更
     * @param auditList
     */
    @Override
    public void updateAuditList(List<String> idList,int auditList) {
        RealisticRecord realisticRecord;
        try {
            for(int i = 0;i < idList.size(); i++) {
                realisticRecord = realisticRecordRepository.findById(Integer.valueOf(idList.get(i))).get();
                realisticRecord.setAuditStatus(auditList);
                realisticRecord.setUpdateDate(new Date());
                realisticRecord.setUpdateBy(realisticRecord.getUpdateBy());
                realisticRecord.setRejectionReason("");
                realisticRecordRepository.saveAndFlush(realisticRecord);
            }
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
    }

    /**
     * 待确认以外查询
     * @param page,size
     */
    @Override
    public Page<RealisticRecord> findExceptList(int page, int size) {
        Specification querySpecification = new Specification() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                List<Integer> auditStatus = Arrays.asList(1,2,3,4,5,6,7);
                predicates.add(criteriaBuilder.in(root.get("auditStatus").as(Integer.class)).value(auditStatus));
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
        PageRequest pageRequest = PageRequest.of(page-1, size, Sort.by(Sort.Direction.DESC,"updateDate"));
        return realisticRecordRepository.findAll(querySpecification,pageRequest);
    }

    /**
     * 更新
     * @param rejectionReason
     * @return
     */
    @Override
    public RealisticRecord updateRejectionReason(String id, String rejectionReason) {
        RealisticRecord realisticRecord = realisticRecordRepository.findById(Integer.parseInt(id)).get();
        realisticRecord.setRejectionReason(rejectionReason);
        realisticRecord.setUpdateDate(new Date());
        return realisticRecordRepository.saveAndFlush(realisticRecord);
    }

    /**
     * 写实记录信息数据公示展示
     * @param page,size
     */
    @Override
    public Page<RealisticRecord> findDisplayList(RealisticRecord realisticRecord,int page, int size) {
        Specification querySpecification = new Specification() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                List<Predicate> studentNamePredicates = new ArrayList<>();
                if(realisticRecord != null){
                    Integer dimension = realisticRecord.getDimension();
                    String classify = realisticRecord.getClassify();
                    String studentName = realisticRecord.getStudentName();
                    if (!StringUtils.isEmpty(studentName))
                    {
                        studentNamePredicates.add(criteriaBuilder.like(root.get("studentName").as(String.class),'%' + studentName + '%'));
                        studentNamePredicates.add(criteriaBuilder.like(root.get("studentNumber").as(String.class),'%' + studentName + '%'));
                        predicates.add(criteriaBuilder.or(studentNamePredicates.toArray(new Predicate[studentNamePredicates.size()])));
                    }
                    if (dimension != null)
                    {
                        predicates.add(criteriaBuilder.equal(root.get("dimension").as(Integer.class),dimension));
                    }
                    if (!StringUtils.isEmpty(classify))
                    {
                        predicates.add(criteriaBuilder.equal(root.get("classify").as(String.class),classify));
                    }
                }
                List<Integer> auditStatus = Arrays.asList(2,6);
                predicates.add(criteriaBuilder.in(root.get("auditStatus").as(Integer.class)).value(auditStatus));
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
        PageRequest pageRequest = PageRequest.of(page-1, size, Sort.by(Sort.Direction.DESC,"updateDate"));
        return realisticRecordRepository.findAll(querySpecification,pageRequest);
    }

    /**
     * 根据学校ID和班级ID查询所有
     * @param schoolId,classId
     */
    @Override
    public List<RealisticRecord> findAllBySchoolIdAndClassId(Integer schoolId,Integer classId){
        return realisticRecordRepository.findAllBySchoolIdAndClassId(schoolId,classId);
    }
}
